﻿using System;
using System.Collections.Generic;
using System.Linq;
using FluentAssertions;
using Microsoft.Practices.Unity;
using NUnit.Framework;
using ReactiveGraph.Core;
using ReactiveGraph.Core.Configuration.Containers;
using ReactiveGraph.Object.Configuration;
using ReactiveGraph.Object.Configuration.Containers;

namespace ReactiveGraph.Object.Tests
{
    [TestFixture]
    public class ReactiveObjectTests
    {
        private UnityContainer _container;

        [SetUp]
        public void Setup()
        {
            _container = new UnityContainer();
            _container.AddExtension(new UnityObjectExtension());
           
        }

        [Test]
        public void PropertiesAreAutomaticallyInstantiatedAndWiredUpOnInitialize()
        {
            var context = _container.Resolve<Context>();
            var foo = new Foo();
            foo.SetContext(context);
            foo.Initialize();
            foo.FooName.Value = "Hey";
            foo.IsValid.Value = true;

            (foo as IReactiveNode).Properties.Should().BeEquivalentTo(foo.FooName, foo.IsValid);
        }

        [Test]
        public void PropertiesThatHaveManuallyBeenSetAreNotOverwrittenButWired()
        {
            var context = _container.Resolve<Context>();
            var foo = new Foo();
            foo.SetContext(context);
            var manual = new Property<string>("FooName");
            foo.FooName = manual;
            foo.Initialize();
            foo.FooName.Should().Be(manual);
            (foo as IReactiveNode).Properties.Should().BeEquivalentTo(foo.FooName, foo.IsValid);
        }

        [Test]
        public void ChildNodesAreAutomaticallyInstantiated()
        {
            var foo = _container.Resolve<Foo>();
            foo.FooName.Value = "Hey";
            foo.Bar.Name.Value = "name";
        }

        [Test]
        public void PropertyChangedOnNode()
        {
            var foo = _container.Resolve<Foo>();
            var items = new List<IProperty>();
            foo.PropertyChanged().Do(items.Add).Subscribe();

            foo.IsValid.Value = true;
            items.Should().HaveCount(1);
        }

        [Test]
        public void PropertyChangedOnProperty()
        {
            var foo = _container.Resolve<Foo>();
            var items = new List<bool>();
            foo.IsValid.PropertyChanged().Do(items.Add).Subscribe();

            foo.IsValid.Value = true;
            items.Should().HaveCount(1);
        }

        
    }
}
